package com.ld.web.shiro;

import com.ld.api.rpc.RoleSupportService;
import com.ld.api.rpc.UserSupportService;
import com.ld.entity.Role;
import com.ld.entity.User;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.thymeleaf.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 认证
 */
@Component
public class UserRealm extends AuthorizingRealm {

    @Reference(version = "1.0")
    private UserSupportService userService;
    @Reference(version = "1.0")
    private RoleSupportService roleService;
    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("UserRealm.class:授权----------");
        User user = (User) principalCollection.getPrimaryPrincipal();
        Long userId = user.getId();

       List<Role> roles = roleService.selectRolesByUserId(userId);
        //用户权限列表
        Set<String> permsSet = new HashSet<String>();
        if(!CollectionUtils.isEmpty(roles)){
            for (Role role:roles) {
                permsSet.add(role.getRoleName());
            }
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("UserRealm.class:认证----------");
        String username = (String) token.getPrincipal();
       User user = userService.selectUserByUserName(username);

        //密码加密
        //sha256加密
        String password = new String((char[]) token.getCredentials());
//        password = new Sha256Hash(password).toHex();
        //查询用户信息
        if(ObjectUtils.isEmpty(user)){
            throw new UnknownAccountException("该账号不存在");
        }
        if(StringUtils.isEmpty(password) || !StringUtils.equals(password,user.getPassWord())){
            throw new IncorrectCredentialsException("账号或密码不正确");
        }
//        if(user.getStatus()==0){
//            throw new LockedAccountException("账户被锁定");
//        }
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(true);
        session.setAttribute("curUser", user);

        user.setLastLoginTime(LocalDateTime.now());
        user.setOnline(true);
        boolean b = userService.updateUserById(user);

        return new SimpleAuthenticationInfo(
                user, //用户名
                password, //密码
                this.getClass().getName()  //realm name
        );
    }

    public static void main(String[] args) {
        String password = "password";
        password = new Sha256Hash(password).toHex();
        System.out.println(password);
    }
}
